1# Transforms Tutorial
  2
  3<!-- TOC -->
  4
  5## Translation
  6The `translate()` command is very simple:
  7```openscad
  8include <BOSL2/std.scad>
  9#sphere(d=20);
 10translate([0,0,30]) sphere(d=20);
 11```
 12
 13But at a glance, or when the formula to calculate the move is complex, it can be difficult to see
 14just what axis is being moved along, and in which direction.  It's also a bit verbose for such a
 15frequently used command.  For these reasons, BOSL2 provides you with shortcuts for each direction.
 16These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`:
 17```openscad
 18include <BOSL2/std.scad>
 19#sphere(d=20);
 20up(30) sphere(d=20);
 21```
 22
 23```openscad
 24include <BOSL2/std.scad>
 25#sphere(d=20);
 26down(30) sphere(d=20);
 27```
 28
 29```openscad
 30include <BOSL2/std.scad>
 31#sphere(d=20);
 32fwd(30) sphere(d=20);
 33```
 34
 35```openscad
 36include <BOSL2/std.scad>
 37#sphere(d=20);
 38back(30) sphere(d=20);
 39```
 40
 41```openscad
 42include <BOSL2/std.scad>
 43#sphere(d=20);
 44left(30) sphere(d=20);
 45```
 46
 47```openscad
 48include <BOSL2/std.scad>
 49#sphere(d=20);
 50right(30) sphere(d=20);
 51```
 52
 53There is also a more generic `move()` command that can work just like `translate()`:
 54```openscad
 55include <BOSL2/std.scad>
 56#sphere(d=20);
 57move([30,-10]) sphere(d=20);
 58```
 59
 60## Scaling
 61The `scale()` command is also fairly simple:
 62```openscad
 63include <BOSL2/std.scad>
 64scale(2) cube(10, center=true);
 65```
 66
 67```openscad
 68include <BOSL2/std.scad>
 69scale([1,2,3]) cube(10, center=true);
 70```
 71
 72If you want to only change the scaling on one axis, though, BOSL2 provides clearer
 73commands to do just that; `xscale()`, `yscale()`, and `zscale()`:
 74```openscad
 75include <BOSL2/std.scad>
 76xscale(2) cube(10, center=true);
 77```
 78```openscad
 79include <BOSL2/std.scad>
 80yscale(2) cube(10, center=true);
 81```
 82```openscad
 83include <BOSL2/std.scad>
 84zscale(2) cube(10, center=true);
 85```
 86
 87
 88## Rotation
 89The `rotate()` command is fairly straightforward:
 90```openscad
 91include <BOSL2/std.scad>
 92rotate([0,30,0]) cube(20, center=true);
 93```
 94
 95It is also a bit verbose, and can, at a glance, be difficult to tell just how it is rotating.
 96BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`:
 97```openscad
 98include <BOSL2/std.scad>
 99xrot(30) cube(20, center=true);
100```
101
102```openscad
103include <BOSL2/std.scad>
104yrot(30) cube(20, center=true);
105```
106
107```openscad
108include <BOSL2/std.scad>
109zrot(30) cube(20, center=true);
110```
111
112The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`:
113```openscad
114include <BOSL2/std.scad>
115rot([0,30,15]) cube(20, center=true);
116```
117
118All of the rotation shortcuts can take a `cp=` argument, that lets you specify a
119centerpoint to rotate around:
120```openscad
121include <BOSL2/std.scad>
122cp = [0,0,40];
123color("blue") move(cp) sphere(d=3);
124#cube(20, center=true);
125xrot(45, cp=cp) cube(20, center=true);
126```
127
128```openscad
129include <BOSL2/std.scad>
130cp = [0,0,40];
131color("blue") move(cp) sphere(d=3);
132#cube(20, center=true);
133yrot(45, cp=cp) cube(20, center=true);
134```
135
136```openscad
137include <BOSL2/std.scad>
138cp = [0,40,0];
139color("blue") move(cp) sphere(d=3);
140#cube(20, center=true);
141zrot(45, cp=cp) cube(20, center=true);
142```
143
144You can also do a new trick with it.  You can rotate from pointing in one direction, towards another.
145You give these directions using vectors:
146```openscad
147include <BOSL2/std.scad>
148#cylinder(d=10, h=50);
149rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50);
150```
151
152There are several direction vectors constants and aliases you can use for clarity:
153
154Constant                       | Value        | Direction
155------------------------------ | ------------ | --------------
156`CENTER`, `CTR`                | `[ 0, 0, 0]` | Centered
157`LEFT`                         | `[-1, 0, 0]` | Towards X-
158`RIGHT`                        | `[ 1, 0, 0]` | Towards X+
159`FWD`, `FORWARD`, `FRONT`      | `[ 0,-1, 0]` | Towards Y-
160`BACK`                         | `[ 0, 1, 0]` | Towards Y+
161`DOWN`, `BOTTOM`, `BOT`        | `[ 0, 0,-1]` | Towards Z-
162`UP`, `TOP`                    | `[ 0, 0, 1]` | Towards Z+
163
164This lets you rewrite the above vector rotation more clearly as:
165```openscad
166include <BOSL2/std.scad>
167#cylinder(d=10, h=50);
168rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
169```
170
171
172## Mirroring
173The standard `mirror()` command works like this:
174```openscad
175include <BOSL2/std.scad>
176#yrot(60) cylinder(h=50, d1=20, d2=10);
177mirror([1,0,0]) yrot(60) cylinder(h=50, d1=20, d2=10);
178```
179
180BOSL2 provides shortcuts for mirroring across the standard axes; `xflip()`, `yflip()`, and `zflip()`:
181```openscad
182include <BOSL2/std.scad>
183#yrot(60) cylinder(h=50, d1=20, d2=10);
184xflip() yrot(60) cylinder(h=50, d1=20, d2=10);
185```
186
187```openscad
188include <BOSL2/std.scad>
189#xrot(60) cylinder(h=50, d1=20, d2=10);
190yflip() xrot(60) cylinder(h=50, d1=20, d2=10);
191```
192
193```openscad
194include <BOSL2/std.scad>
195#cylinder(h=50, d1=20, d2=10);
196zflip() cylinder(h=50, d1=20, d2=10);
197```
198
199All of the flip commands can offset where the mirroring is performed:
200```openscad
201include <BOSL2/std.scad>
202#zrot(30) cube(20, center=true);
203xflip(x=-20) zrot(30) cube(20, center=true);
204color("blue",0.25) left(20) cube([0.1,50,50], center=true);
205```
206
207```openscad
208include <BOSL2/std.scad>
209#zrot(30) cube(20, center=true);
210yflip(y=20) zrot(30) cube(20, center=true);
211color("blue",0.25) back(20) cube([40,0.1,40], center=true);
212```
213
214```openscad
215include <BOSL2/std.scad>
216#xrot(30) cube(20, center=true);
217zflip(z=-20) xrot(30) cube(20, center=true);
218color("blue",0.25) down(20) cube([40,40,0.1], center=true);
219```
220
221
222## Skewing
223One transform that OpenSCAD does not perform natively is skewing.
224BOSL2 provides the `skew()` command for that.  You give it multipliers
225for the skews you want to perform.  The arguments used all start with `s`,
226followed by the axis you want to skew along, followed by the axis that
227the skewing will increase along.  For example, to skew along the X axis as
228you get farther along the Y axis, use the `sxy=` argument.  If you give it
229a multiplier of `0.5`, then for each unit further along the Y axis you get,
230you will add `0.5` units of skew to the X axis.  Giving a negative multiplier
231reverses the direction it skews:
232```openscad
233include <BOSL2/std.scad>
234skew(sxy=0.5) cube(10,center=false);
235```
236
237```openscad
238include <BOSL2/std.scad>
239skew(sxz=-0.5) cube(10,center=false);
240```
241
242```openscad
243include <BOSL2/std.scad>
244skew(syx=-0.5) cube(10,center=false);
245```
246
247```openscad
248include <BOSL2/std.scad>
249skew(syz=0.5) cube(10,center=false);
250```
251
252```openscad
253include <BOSL2/std.scad>
254skew(szx=-0.5) cube(10,center=false);
255```
256
257```openscad
258include <BOSL2/std.scad>
259skew(szy=0.5) cube(10,center=false);
260```
261
262